﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Fis.Web.Rules.Service
{
    public class PersonRule : Agile.Engine.Data.DataRule
    {
        string DataTableName = "TCUSTOM";

        public override void ExecuteNonTrans()
        {
            var action = Paramater["action"].ToString();
            System.Data.DataTable data = null;
            switch (action)
            {
                case "schema":
                    data = Model.QueryTable(DataTableName, "1=2");
                    data.Rows.Add(data.NewRow());
                    break;
                case "save":
                    data = Save(int.Parse(Paramater["state"].ToString()));
                    break;
                case "load":
                    data = Model.QueryTable(DataTableName, string.Format("SID='{0}'", Paramater["SID"]));
                    break;
                case "delete":
                    break;
                case "audit":
                    data = Audit();
                    break;
                case "query":
                    data = Model.QueryTable(DataTableName, Paramater["filter"].ToString());
                    if (data.Rows.Count == 0)
                        Message = "查询结果为空";
                    break;
            }

            Result["data"] = (data.Rows.Count > 0) ? Agile.Engine.Utils.ZipUtils.ZipDataTable(data) : null;
        }

        System.Data.DataTable Save(int state)
        {
            var data = Agile.Engine.Utils.ZipUtils.UnZipDataTable(Paramater["data"].ToString());
            var da = new Agile.Engine.Data.DataAccess() { Context = Model.DataContext, TableName = DataTableName };
            switch (state)
            {
                case 1://addnew
                    data.Rows[0]["SID"] = Guid.NewGuid().ToString();
                    data.Rows[0]["SINDEXDATE"] = DateTime.Now;
                    data.Rows[0]["FENTERTIME"] = DateTime.Now;
                    da.AddNew(data.Rows[0]);
                    break;
                case 2://modify
                    data.Rows[0]["SINDEXDATE"] = DateTime.Now;
                    da.Update(data.Rows[0]);
                    break;
            }

            return data;
        }

        System.Data.DataTable Audit()
        {
            var data = Agile.Engine.Utils.ZipUtils.UnZipDataTable(Paramater["data"].ToString());
            var da = new Agile.Engine.Data.DataAccess() { Context = Model.DataContext, TableName = DataTableName };

            if (Agile.Engine.Utils.StringUtils.IsEmpty(data.Rows[0]["FBOOKID"]))
            {
                data.Rows[0]["SBOOKID"] = data.Rows[0]["FBOOKID"] = CreateBookID(da);
            }

            var pwd = CreatePassword(6);
            var md5 = Agile.Engine.Utils.StringUtils.ToMD5(pwd);
            data.Rows[0]["FBOOKPWD"] = md5;
            data.Rows[0]["FSTATE"] = 1;
            data.Rows[0]["SINDEXDATE"] = DateTime.Now;
            da.Update(data.Rows[0]);

            Result["Random"] = pwd;

            var common = new CommonRule();
            common.ResetAdminPassword(data.Rows[0]["SBOOKID"].ToString(), md5);

            return data;
        }

        string CreateBookID(Agile.Engine.Data.DataAccess da)
        {
            bool validate = true;
            var param = new System.Collections.Hashtable();

            do
            {
                param["FBOOKID"] = Math.Abs(Guid.NewGuid().GetHashCode());
                validate = (da.GetData(param).Rows.Count > 0);
            } while (validate);

            return param["FBOOKID"].ToString();
        }

        string CreatePassword(int count)
        {
            var upper = InitilizeCharList('A', 26);
            var lower = InitilizeCharList('a', 26);
            var number = InitilizeCharList('0', 10);

            var result = new StringBuilder();
            Random r = new Random(Math.Abs(Guid.NewGuid().GetHashCode()));

            for (var i = 0; i < count; i++)
            {
                if (i % 3 == 0)
                {
                    result.Append(upper[r.Next(0, upper.Count - 1)]);
                }
                else if (i % 2 == 0)
                {
                    result.Append(lower[r.Next(0, lower.Count - 1)]);
                }
                else
                {
                    result.Append(number[r.Next(0, number.Count - 1)]);
                }
            }
            return result.ToString();


        }

        List<char> InitilizeCharList(char ch, int count)
        {
            List<char> list = new List<char>();
            for (var i = 0; i < count; i++)
            {
                var newch = ((int)ch) + i;
                list.Add((char)newch);
            }
            return list;
        }
    }
}
